import 'package:flutter/material.dart';

/// 数字滚动动画组件
class RollingNumber extends StatefulWidget {
  final double value;
  final int decimals;
  final TextStyle style;
  final String prefix;
  final String suffix;
  final Duration duration;

  const RollingNumber({
    super.key,
    required this.value,
    this.decimals = 14,
    required this.style,
    this.prefix = '',
    this.suffix = '',
    this.duration = const Duration(milliseconds: 800),
  });

  @override
  State<RollingNumber> createState() => _RollingNumberState();
}

class _RollingNumberState extends State<RollingNumber>
    with SingleTickerProviderStateMixin {
  late AnimationController _controller;
  late Animation<double> _animation;
  late double _previousValue;
  late double _currentValue;
  late String _lastFormatted; // 上次展示的格式化字符串

  @override
  void initState() {
    super.initState();
    _previousValue = widget.value;
    _currentValue = widget.value;
    _lastFormatted = _format(widget.value);

    _controller = AnimationController(duration: widget.duration, vsync: this);

    _animation = Tween<double>(
      begin: _previousValue,
      end: _currentValue,
    ).animate(CurvedAnimation(parent: _controller, curve: Curves.easeOutCubic));

    _controller.forward();
  }

  @override
  void didUpdateWidget(RollingNumber oldWidget) {
    super.didUpdateWidget(oldWidget);
    final newFormatted = _format(widget.value);
    if (newFormatted != _lastFormatted) {
      // 从上次展示的字符串作为起点，确保极小增量也能触发动画
      _previousValue = double.tryParse(_lastFormatted) ?? _currentValue;
      _currentValue = double.tryParse(newFormatted) ?? widget.value;

      _animation = Tween<double>(
        begin: _previousValue,
        end: _currentValue,
      ).animate(
        CurvedAnimation(parent: _controller, curve: Curves.easeOutCubic),
      );

      _lastFormatted = newFormatted;
      _controller.reset();
      _controller.forward();
    }
  }

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return AnimatedBuilder(
      animation: _animation,
      builder: (context, child) {
        final animatedValue = _animation.value;
        final formattedValue = _format(animatedValue);
        return Text(
          '${widget.prefix}$formattedValue${widget.suffix}',
          style: widget.style,
        );
      },
    );
  }

  String _format(double v) => v.toStringAsFixed(widget.decimals);
}
